package com.buss.core.dao.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.hibernate.type.LongType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.StringType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.buss.core.dao.SysmenuDao;
import com.buss.core.dic.MenuType;
import com.buss.core.model.Sysmenu;
import com.buss.core.persistence.BaseDao;
import com.buss.core.persistence.Paginalbe;
import com.buss.core.persistence.PersistenceCond;
import com.buss.core.persistence.ResultList;

@Repository
public class SysmenuDaoImpl implements SysmenuDao {

	private static final long serialVersionUID = -6401459706509028198L;

	@Autowired
	private BaseDao<Sysmenu> baseDao;
	
	public void editSysMenu(Sysmenu sysMenu) {
		baseDao.edit(sysMenu);
	}

	public Sysmenu loadSysMenu(Long id) {
		return baseDao.get(id, Sysmenu.class);
	}

	public ResultList<Sysmenu> querySysMenu(Long parentId,MenuType menuType,Boolean disabled) {
		String sql = "select sysMenu from Sysmenu sysMenu where " +
				" sysMenu.parentId = :parentId ";
		PersistenceCond cond = new PersistenceCond();		
		cond.add("parentId", parentId);
		if(menuType != null){
			sql += " and sysMenu.menuType = :menuType ";
			cond.add("menuType", menuType);
		}
		if(disabled != null){
			sql += " and sysMenu.disabled = :disabled ";
			cond.add("disabled", disabled);
		}
		sql += "  order by sysMenu.seqNum asc ";
		return baseDao.queryHsqlByIter(sql, cond, null);
	}

	public Map<Long, String> queryRoleMenuToMap(Long[] roleId,Long parentId,MenuType menuType,Boolean disabled,Paginalbe page){
		String sql = "select new com.buss.core.model.Sysmenu(sysMenu.id,sysMenu.code) from Sysmenu sysMenu inner join sysMenu.roles role where role.id in (:roleId) " ;
		PersistenceCond cond = new PersistenceCond();
		cond.add("roleId", roleId);
		if(parentId != null){
			sql += " and sysMenu.parentId = :parentId ";
			cond.add("parentId", parentId);
		}
		if(disabled != null){
			sql += " and sysMenu.disabled = :disabled ";
			cond.add("disabled", disabled);
		}
		if(menuType != null){
			sql += " and sysMenu.menuType = :menuType ";
			cond.add("menuType", menuType);
		}		
		ResultList<Sysmenu> result = baseDao.queryHsqlByIter(sql, cond, page);
		Map<Long,String> map = new HashMap<Long, String>();
		for(Sysmenu menu : result.getData()){
			map.put(menu.getId(), menu.getCode());
		}
		return map;
	}
	
	public ResultList<Sysmenu> queryAllMenuenuByRole(Long[] roleId,Long parentId,MenuType menuType,Boolean disabled,Paginalbe page){
		String sql = "select a.* from (";
		sql += "select id,disabled,code,iconPath,menuType,name,nodeNum,parentId,seqNum,url as menuUrl,1 as checked from core_sysmenu a, core_role_menu b where a.id = b.menuId and b.roleid in (:roleId)";
		sql += " union ";
		sql += "select id,disabled,code,iconPath,menuType,name,nodeNum,parentId,seqNum,url as menuUrl,0 as checked from core_sysmenu where id not in(select menuId from core_role_menu where roleid in (:roleId)) ";
		sql += ") a where 1 = 1 ";		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("roleId", roleId);
		if(parentId != null){
			sql += " and a.parentId = :parentId ";
			map.put("parentId", parentId);
		}
		if(disabled != null){
			sql += " and a.disabled = :disabled ";
			map.put("disabled", disabled);
		}
		if(menuType != null){
			sql += " and a.menuType = :menuType ";
			System.out.println(menuType.toString());
			map.put("menuType", menuType.toString());
		}		
		sql += " order by a.seqNum asc";
		SQLQuery query = baseDao.getSession().createSQLQuery(sql);

		query.addScalar("id",StandardBasicTypes.LONG);
		query.addScalar("code", StandardBasicTypes.STRING);
		query.addScalar("disabled",StandardBasicTypes.BOOLEAN);
		query.addScalar("iconPath",StandardBasicTypes.STRING);
		//query.addScalar("menuType",StandardBasicTypes.SERIALIZABLE);
		query.addScalar("name",StandardBasicTypes.STRING);
		query.addScalar("nodeNum",StandardBasicTypes.LONG);
		query.addScalar("parentId",StandardBasicTypes.LONG);
		query.addScalar("seqNum",StandardBasicTypes.LONG);
		query.addScalar("menuUrl",StandardBasicTypes.STRING);
		query.addScalar("checked",StandardBasicTypes.BOOLEAN);
		query.setResultTransformer(Transformers.aliasToBean(Sysmenu.class));
		ResultList<Sysmenu> rs = baseDao.queryNative(sql, query, map, null);
		return rs;
	}
	
	public ResultList<Sysmenu> querySysMenuByRole(Long[] roleId,Long parentId,MenuType menuType,Boolean disabled,Paginalbe page){
		String sql = "select sysMenu from Sysmenu sysMenu inner join sysMenu.roles role where role.id in (:roleId) " ;
		PersistenceCond cond = new PersistenceCond();
		cond.add("roleId", roleId);
		if(parentId != null){
			sql += " and sysMenu.parentId = :parentId ";
			cond.add("parentId", parentId);
		}
		if(disabled != null){
			sql += " and sysMenu.disabled = :disabled ";
			cond.add("disabled", disabled);
		}
		if(menuType != null){
			sql += " and sysMenu.menuType = :menuType ";
			cond.add("menuType", menuType);
		}		
		return baseDao.queryHsqlByIter(sql, cond, page);		
	}
	
	public void saveSysMenu(Sysmenu sysMenu) {
		baseDao.save(sysMenu);

	}

	public Sysmenu mergeSysMenu(Sysmenu sysMenu){
		return baseDao.saveOrEdit(sysMenu);
	}
	
	public void deleteMenu(Long[] ids){
		String sql = "delete from Sysmenu sysMenu where sysMenu.id in (:ids)";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("ids", ids);
		baseDao.excuteHsql(sql, map);
	}
	
	public void updateNodeNum(Long id,long num){
		if(id == null){
			return;
		}
		String sql = "update Sysmenu sysMenu set sysMenu.nodeNum = sysMenu.nodeNum - :num where sysMenu.id = :id";
		PersistenceCond cond = new PersistenceCond();
		cond.add("id", id);
		cond.add("num", num);
		baseDao.excuteHsql(sql, cond);
	}
	
}
